<template>
	<view class="main">
		<!-- ======================================【顶部栏】====================================== -->
		<MyHead :title="title"></MyHead>
		<!-- ===================================================================================== -->
		
		
		<!-- ======================================【聊天界面】====================================== -->
		<scroll-view scroll-y class="container" :scroll-into-view="scrollToView">			
			<!-- 开启聊天界面 -->
			<view class="chatBox" v-for="(item, index) in ChatLists" :key="item.chatId" :id="'msg'+item.chatId">
				<view class="AiChatUser" v-if="item.chatType === 'AiChat' || item.chatType === 'Thinking'">
					<view class="avatar">
						<image src="https://gd-hbimg.huaban.com/a20371a173ff30590027813fe2756b631e7dab7b85517-d9DraL_fw480webp" mode="scaleToFill"></image>
					</view>
					
					<view class="AiChat_Init_Text" v-html="item.content"></view>
				</view>
				
				<view class="MyChatUser" v-if="item.chatType === 'MyChat'">
					<view class="AiChat_Init_Text" v-html="item.content"></view>
					
					<view class="avatar">
						<image src="https://gd-hbimg.huaban.com/1598e5d4c8fff2d9ae14cdfd6faec7ee8b8d2640176c6-QJ4L0V_fw480webp" mode="scaleToFill"></image>
					</view>
				</view>
			</view>
		</scroll-view>
		<!-- ==================================================================================================== -->
		
		
		<!-- ======================================【底部发消息的输入框区域】====================================== -->
		<view class="BottomInputArea">
			<!-- 发送附件（图片、文件...等） -->
			<view class="attachment" @click="saveChatHistory">
				<image src="https://gd-hbimg.huaban.com/3a8d3eaf7081865f2af5ca95089bdd904125f2654854-BqYqW5_fw480webp" mode="scaleToFill"></image>
			</view>
			
			<!-- 输入框 -->
			<view class="input">
				<input type="text" placeholder="输入要发送的信息" v-model="MyText" @input="changeHasText" @confirm="sendMessage"/>
			</view>
			
			<!-- 发送按钮 -->
			<view class="send" @click="sendMessage" v-show="hasText"> <!-- 输入了内容之后的允许发送按钮 -->
				<image src="https://gd-hbimg.huaban.com/2d651589a94852418ae3b7580bba30ae478f54e5117d-ILdWPm_fw480webp" mode="scaleToFill"></image>
			</view>
			<view class="send" @click="showToast" v-show="!hasText"> <!-- 未输入内容之前的禁用发送按钮 -->
				<image src="https://gd-hbimg.huaban.com/3294b0313aa00ef54f03bb767b4ffcf3810eeb6d1435-iax0MO_fw480webp" mode="scaleToFill"></image>
			</view>
		</view>
		<!-- ==================================================================================================== -->
  </view>
</template>

<script>
  import tagApi from '../../api/intro/intro.js'
  export default {
    data() {
		return {
			title: 'AI聊天页面',
			pathUrl: '/pages/AiChat/AiChat',
			hasText: false,
			MyText: '',
			historyType: null,
			historyId: null,
			//控制滑动区域自动滚动
			scrollToView: '',
			currentUser: {
				uuid: '',
				avatarUrl: 'https://gd-hbimg.huaban.com/1598e5d4c8fff2d9ae14cdfd6faec7ee8b8d2640176c6-QJ4L0V_fw480webp', // 替换为默认头像路径
				userName: '未登录',
			},
			ChatLists: [
				{
					chatId: 1,
					chatType: 'AiChat',
					content: '你好！作为一个认知智能模型，很高兴为您提供帮助。请问有什么问题我可以帮您解答吗？'
				}
			]
		};
    },
	onLoad() {
		// 页面加载时调用
		// this.connectWebSocket();
		// this.historyType = params.type
		// this.historyId = params.id
	},
	onShow() {
		let currentUser = uni.getStorageSync('currentUser');
		
		if (currentUser) {
			console.log(currentUser)
			this.currentUser = currentUser
			this.hasCurrentUser = true
		}
	},
	onUnload() {
		// 页面卸载时调用，关闭 WebSocket 连接
		// uni.closeSocket();
	},
    methods:　{	
		// 输入框开始输入内容，控制发送按钮的样式
		changeHasText(){
			if(this.MyText.trim() !== '') {
				this.hasText = true
			}else{
				this.hasText = false
			}
		},
		// 点击禁用按钮触发
		showToast() {
			// 显示提示框
			uni.showToast({
				title: '请勿发送空白字符',
				icon: 'none', // 不显示图标
				duration: 2000 // 显示时长
			});
			this.MyText = ''
		},
		// 保存聊天记录
		saveChatHistory(){
			if(this.hasCurrentUser){
				// 显示加载框
				uni.showLoading({ title: '保存中...' });
				setTimeout(() => {
					uni.hideLoading()
					
					let length = this.$store.state.LatlyList.length
					const now = new Date()
					
					
					let chatHistory = {
						historyId: length + 1,
						historyTime: this.formatDate(now),
						historyTitle: this.getTitle() + '...',
						historyType: '最近聊天',
						historyContent: this.ChatLists
					}
					this.$store.commit('addToLatlyList', chatHistory)  // 用vueX保存ai聊天记录
					console.log(this.$store.state.LatlyList); // 直接打印状态
					
					uni.showToast({
						title: '保存成功',
						icon: 'success',
						duration: 2000 // 显示时长
					});
				}, 1000)
			} else {
				// 如果 currentUser 不存在，提示先登录
				uni.showModal({
					title: '当前未登录',
					content: '请先登录/注册',
					confirmText: '确认登录',
					conselText: '取消授权',
					success: (res) => {
						if(res.confirm){
							uni.navigateTo({
								url: '../../pages/login/login'
							})
						} else {
							uni.showToast({
								icon: 'none',
								title: "保存失败，【登录后】可保存"
							});
						}
					},
					fail: (err) => {
						// 模态对话框调用失败
						console.log("模态对话框调用失败：", err);
					}
				});
			}
		},
		formatDate(date) {
			const year = date.getFullYear();
			const month = (date.getMonth() + 1).toString().padStart(2, '0'); // 月份是从0开始的，所以需要+1
			const day = date.getDate().toString().padStart(2, '0');
			const hours = date.getHours().toString().padStart(2, '0');
			const minutes = date.getMinutes().toString().padStart(2, '0');

			return `${month}-${day}-${hours}:${minutes}`;
		},
		getTitle(){
			let length = this.ChatLists[1].length
			return this.ChatLists[1].substring(0,length)
		},
		
		//=========================输入完，点击发送按钮触发=========================
		sendMessage(){
			//将输入框的消息头尾去掉空白字符，判断一下“我”输入的东西是不是空白字符
			let content = this.MyText.trim()
			console.log(content)
			
			//不是空白字符就正常输出
			if(content !== ''){
				// 先添加我的消息到页面
				let chatItem = {
					chatId: this.ChatLists.length + 1,
					chatType: 'MyChat',
					content: this.MyText
				}
				this.ChatLists.push(chatItem)
				
				
				// 然后前端通过样式响应,马上渲染ai"思考加载"的样式
				let thinkItem = {
					chatId: this.ChatLists.length + 1,
					chatType: 'AiChat',
					content: 'AI思考中...'
				}
				this.ChatLists.push(thinkItem)
				// 这是为了马上自动更新页面像底部滚动
				this.$nextTick(() => {
					this.scrollToView = 'msg' + this.ChatLists[this.ChatLists.length - 1].chatId
				})
				
				
				// 接下来就是AI正式返回响应,
				let params = {
				    "chatId": "a01",//这里直接填用户的user_id
				    "stream": false,
				    "detail": false,
				    "messages": [//这就是对话内容对象，但不用把用户已说的历史记录写进来
				        {
				            "content": this.MyText,
				            "role": "user"
				        }
				    ]
				}
				uni.request({
					url: 'https://fffal.iirl.top/api/v1/chat/completions',
					method: 'POST',
					header: {
						Authorization: 'Bearer fastgpt-VF9lWPEqXucj6aaF7FKPyurMtveiLlaTv9l9d4lyhIy56BOqaIeU'
					},
					// enableChunked: true, // 开启流式传输
					data: params, // 将对象转换为JSON字符串
					success: res => {
						console.log(res)
						// console.log(res.data.choices[0].message.content);
						// 当AI结果相应成功后,会马上删除刚刚的"AI加载"消息,取而代之是ai真正的回复
						setTimeout(() => {
							this.ChatLists.pop() // 删除刚刚添加的"AI正在思考..."加载
							let content = {
								chatId: this.ChatLists.length + 1,
								chatType: 'AiChat',
								content: res.data.choices[0].message.content
							}
							this.ChatLists.push(content)
							this.typeWriterEffect(content, this.ChatLists.length - 1); // 调用打字机效果
						}, 1000)
						
						// 再次让消息窗口自动滚到底部
						this.$nextTick(() => {
							this.scrollToView = 'msg' + this.ChatLists[this.ChatLists.length - 1].chatId
						})
					},
					fail: err => {
						console.log(err);
					}
				});
			//是空白字符就输出提示信息
			}else{
				uni.showToast({
					title: '请勿发送空白字符',
					icon: 'none', // 不显示图标
					duration: 2000 // 显示时长
				});
			}
			
			// 最后别忘了，发送完信息就把输入框信息清空
			this.MyText = ''
		},
		//============================================================================
		
		
		//===============================实现打字机效果================================
		typeWriterEffect(chatItem, index) {
			// 获取到当前会话列表最后一条信息，也就是刚刚ai的响应
		    const content = this.ChatLists[index].content;
			
			// 这里开始实现打字机，只需要用setInterval定时器，每隔100毫秒输出一个字，直到clearInterval执行
			let i = 0;
		    const intervalId = setInterval(() => {
				// this.$set非常非常重要！！！这是vue提供的一个响应式更新【对象】的方法！！！
				// 语法就是：this.$set(对象，属性名，新值)
				// 我们要做的逻辑就是：每隔100毫秒，将ChatLists的最后一个消息这个【对象】的【content】值更新就行了
				this.$set(this.ChatLists[index], 'content', content.substring(0, i + 1)); // 更新内容
				i++;
				
				//-----------------当所有字符都显示后清除定时器-----------------
				if (i >= content.length) {
					clearInterval(intervalId); // 当所有字符都显示后清除定时器
				}
				//------------------------------------------------------------
		    }, 100); // 每隔100毫秒添加一个字符
		},
		//============================================================================
    },
  }
</script>



<style>
	page{
		background-image: url('https://gd-hbimg.huaban.com/68bb9dee1eed7f34673120d61b18a29d88adcb83713c9-hDYMPo_fw480webp');
		background-size: 100% 100%;
	}
</style> 

<style lang="less" scoped>
	.main {
		.container{
			width: 100%;
			height: 79.5vh;
			padding-top: 80upx;
			box-sizing: border-box;
			.chatBox{
				color: #fff;
				.AiChatUser{
					margin: auto;
					width: 90%;
					display: flex;
					margin-bottom: 50upx;
					justify-content: start;
					.avatar{
						width: 90upx;
						height: 90upx;
						image{
							width: 100%;
							height: 100%;
							border-radius: 50%;
							background-color: #a6afb2c2;
						}
						margin-right: 20upx;
						border-radius: 50%;
					}
					
					.AiChat_Init_Text{
						max-width: 66%;
						background-color: #a6afb2c2;
						border-radius: 20px;
						padding: 25upx;
						box-sizing: border-box;
					}
				}
				.MyChatUser{
					margin: auto;
					width: 90%;
					display: flex;
					justify-content: flex-end;
					margin-bottom: 50upx;
					.avatar{
						width: 90upx;
						height: 90upx;
						image{
							width: 100%;
							height: 100%;
							border-radius: 50%;
							background-color: #a6afb2c2;
						}
						margin-left: 20upx;
						border-radius: 50%;
					}
					
					.AiChat_Init_Text{
						max-width: 66%;
						background-color: #a6afb2c2;
						border-radius: 20px;
						padding: 25upx;
						box-sizing: border-box;
					}
				}
			}
		}
		
		.BottomInputArea{
			width: 100%;
			height: 156rpx;
			background-color: #9994947d;
			position: fixed;
			bottom: 0;
			left: 0;
			right: 0;
			z-index: 1000;
			display: flex;
			.attachment{
				width: 60rpx;
				height: 60rpx;
				margin-left: 30upx;
				margin-top: 31upx;
				image{
					width: 100%;
					height: 100%;
				}
			}
			.input{
				width: 66%;
			    height: 59%;
			    margin-top: 25rpx;
			    margin-left: 30upx;
			    padding-left: 5px;
			    border-radius: 12px;
			    box-sizing: border-box;
			    background-color: #ffffff63;
				input{
					color: #fff;
				    width: 92%;
					font-size: 19px;
				    margin: auto;
				    border-radius: 12px;
				    height: 90%;
				    background-color: #ffffff00;
				}
			}
			.send{
				width: 60upx;
				height: 60upx;
				margin-top: 37upx;
				margin-left: 26rpx;
				image{
					width: 100%;
					height: 100%;
				}
			}
		}
	}
</style>
